﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace MidiPlayer
{
    [Serializable]
    class MidiPlayerSettings : ISerializable
    {

        #region Save Version
        private const int SaveVer02 = 2;
        private const int SaveVer03 = 3;

        private const int SaveLatest = SaveVer03;
        #endregion 


        #region Members
        private string _playbackFile;
        private PlaybackSettingsDto _playSettings = new PlaybackSettingsDto();
        private MidiSettingsDto _midiSettings = new MidiSettingsDto();

        public string PlaybackFile
        {
            get { return _playbackFile; }
            set { _playbackFile = value; }
        }

        public PlaybackSettingsDto PlaySettings
        {
            get { return _playSettings; }
            set { _playSettings = value; }
        }

        public MidiSettingsDto MidiSettings
        {
            get { return _midiSettings; }
            set { _midiSettings = value; }
        }

        #endregion



        public MidiPlayerSettings()
        {
        }

        #region Serialization

        private static string _appFolderName = "MidiPlayer";
        private static string _appFileName = "config.dat";

        public static String GetDefaultFilename()
        {
            string folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                                         _appFolderName);
            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
            }
            return Path.Combine(folder, _appFileName);
        }

        public MidiPlayerSettings(SerializationInfo info, StreamingContext ctxt)
        {
            var saveVersion = (int)info.GetValue("ConfigVersion", typeof(int));

            if (saveVersion >= SaveVer02)
            {
                PlaybackFile = (string) info.GetValue("File", typeof (string));
                PlaySettings = (PlaybackSettingsDto) info.GetValue("PlaySet", typeof (PlaybackSettingsDto));
            }
            if (saveVersion >= SaveVer03)
            {
                MidiSettings = (MidiSettingsDto)info.GetValue("MidiSet", typeof(MidiSettingsDto));
            }
        }


        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("ConfigVersion", SaveLatest);
            
            info.AddValue("File", PlaybackFile);
            info.AddValue("PlaySet", PlaySettings);
            info.AddValue("MidiSet", MidiSettings);
            // TODO: Add other class members here

        }

        public void SaveSettings(string filename)
        {
            Stream stream = File.Open(filename, FileMode.Create);
            var bFormatter = new BinaryFormatter();
            bFormatter.Serialize(stream, this);
            stream.Close();
        }

        public static MidiPlayerSettings LoadSettings(string filename)
        {
            if (!File.Exists(filename)) return new MidiPlayerSettings();

            Stream stream = File.Open(filename, FileMode.Open);
            var bFormatter = new BinaryFormatter();
            var oSettingsToLoad = (MidiPlayerSettings)bFormatter.Deserialize(stream);
            stream.Close();
            return oSettingsToLoad;
        }
        #endregion

        #region Validation
        public void Validate()
        {
            if (String.IsNullOrEmpty(PlaybackFile))
                throw new ArgumentException("Playback file not specified");

            if(!File.Exists(PlaybackFile))
            {
                throw new ArgumentException("Playback file ("+ PlaybackFile + ") does not exist");
            }

            PlaySettings.Validate();
        }
        #endregion
    }
}
